'''
Created on 2010-1-3

@author: wangyongtao
'''

from google.appengine.ext import db
from google.appengine.ext.db import polymodel
import logging

DEFAULT_LIMIT = 20

class app(polymodel.PolyModel):
    name = db.StringProperty(required=True)
    free = db.BooleanProperty(default=True)
    active = db.BooleanProperty(default=False)
    displayname = db.StringProperty()
    icon = db.LinkProperty()
    logo = db.LinkProperty()
    price = db.FloatProperty()
    desc = db.TextProperty()
    created = db.DateTimeProperty(auto_now_add=True)
    updated = db.DateTimeProperty(auto_now=True)
    
    def get_screens(self):
        return screen.all().filter("refapp =", self).order("order").fetch(1000)
    
    def add_screen(self, url, order, width = None, height=None):
        keyname = "%s_%s_%d"%(self.name, url, int(order))
        s = screen.get_or_insert(keyname,  refapp = self, url = db.Link(url), order = int(order))
        putNeeded = False
        if width is not None:
            s.width = int(width)
            putNeeded = True
        if height is not None:
            s.height = int(height)
            putNeeded = True
        if putNeeded:
            s.put()
        return s
    def get_last_screen_order(self):
        s = screen.all().filter("refapp =", self).order("-order").get()
        if s:
            return s.order
        else:
            return 0
        
class android(app):
    package = db.StringProperty(required=True)
    versionmin = db.IntegerProperty(default=3)
    
    @staticmethod
    def get_all_apps(non_active=True):
        q = android.all()
        if not non_active:
            q.filter('active =', True)
        return q.order("created").fetch(1000)
    
    @staticmethod
    def add_app(name, dname, icon, desc, logo = None, free=True, active=True, package=None, minsdk = 3):
        if not name: return None
        if len(name.strip()) == 0: return None
        name = name.strip().lower()
        keyname = "android_%s"%name
        a = android.get_or_insert(keyname, name=name, free=free, active=active, displayname = dname.strip(), package = package, versionmin = minsdk)
        if icon is not None:
            a.icon = db.Link(icon.strip())
        if logo is not None:
            a.logo = db.Link(logo.strip())
        if desc is not None:
            a.desc = desc.strip()
        
        a.put()
        return a
    
    @staticmethod
    def get_app(name):
        if not name: return None
        return android.all().filter('name =', name.strip().lower()).get()
    
class iphone(app):
    urlitunes = db.LinkProperty(required=True)
    ipad = db.BooleanProperty(default=False)
    
    @staticmethod
    def get_all_apps(non_active=True):
        q = iphone.all()
        if not non_active:
            q.filter('active =', True)
        return q.order("created").fetch(1000)
    
    @staticmethod
    def get_app(name):
        if not name: return None
        return iphone.all().filter('name =', name.strip().lower()).get()
    
class screen(db.Model):
    refapp = db.ReferenceProperty(app)
    width = db.IntegerProperty()
    height = db.IntegerProperty()
    url = db.LinkProperty(required=True)
    order = db.IntegerProperty()
    created = db.DateTimeProperty(auto_now_add=True)
    updated = db.DateTimeProperty(auto_now=True) 

class setting(db.Model):
    name = db.StringProperty(required=True)
    value = db.StringProperty(required=True)
    type = db.StringProperty(required=True, choices=set(["bool", "int", "float", "string"]))
    created = db.DateTimeProperty(auto_now_add=True)
    updated = db.DateTimeProperty(auto_now=True)
    
    @staticmethod
    def _add_setting(name, value, type, update=False):
        q = db.Query(setting).filter('name =', name)
        s = q.fetch()
        if s:
            if update:
                s.value = value
                s.type = type
            else:
                logging.error('the specified setting [%s] has already existed'%name)
                return False
        else:
            s = setting(name = name, value = value, type = type)
        s.put()
        return True
    
    @staticmethod
    def get_setting(name):
        result = None
        if not name:
            return result
        q = db.Query(setting).filter('name =', name)
        s = q.get()
        if not s:
            return result
        if s.type == 'bool':
            result = bool(s.value)
        elif s.type == 'int':
            result = int(s.value)
        elif s.type == 'float':
            result = float(s.value)
        else:
            result = s.value
        return result
            
    @staticmethod
    def add_setting_bool(name, value):
        bVal = bool(value)
        type = 'bool'
        setting._add_setting(name, str(bVal), type)
    
    @staticmethod
    def add_setting_int(name, value):
        intVal = int(value)
        type = 'int'
        setting._add_setting(name, intVal, type)
        
    @staticmethod
    def add_setting_float(name, value):
        floatVal = float(value)
        type = 'float'
        setting._add_setting(name, floatVal, type)
    
    @staticmethod
    def add_setting_string(name, value):
        strVal = str(value)
        type = 'string'
        setting._add_setting(name, strVal, type)  
        
class Feedback(db.Model):
    name = db.StringProperty(required=True)
    email = db.EmailProperty(required=True)
    app = db.StringProperty()
    title = db.StringProperty()
    content = db.TextProperty()
    created = db.DateTimeProperty(auto_now_add=True)
    updated = db.DateTimeProperty(auto_now=True)
    
    @staticmethod
    def get_feedbacks(limit, offset):
        limit = int(limit)
        if not limit:
            limit = DEFAULT_LIMIT
        offset = int(offset)
        if not offset:
            offset = 0
        result = []
        q = db.Query(Feedback).order('-created').fetch(limit, offset)
        if q:
            for item in q:
                result.append(item)
        return result
    
    @staticmethod
    def add_feedback(name, email, content, app = None, title = None):
        f = Feedback(name = name, email = email)
        f.content = content
        if not app:
            f.app = app
        if not title:
            f.title = title
        return f.put()
